use tokio::net::{TcpListener, TcpStream};
use tokio::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> io::Result<()> {
    println!("Hello, echo server!");
    let listener = TcpListener::bind("127.0.0.1:8081").await.unwrap();
    loop {
        let (mut socket, _) = listener.accept().await?;

        tokio::spawn(async move {
            // handle_connection(socket).await;
            handle_connection_by_buffer_copy(socket).await;
        });
    }
}

async fn handle_connection(socket: TcpStream) {
    let (mut rd, mut wr) = io::split(socket);
    // copy data here
    if io::copy(&mut rd, &mut wr).await.is_err() {
        eprintln!("failed to copy");
    }
}

async fn handle_connection_by_buffer_copy(mut socket: TcpStream) {
    let mut buf = vec![0; 1024];

    loop {
        match socket.read(&mut buf).await {
            Ok(0) => return,
            Ok(n) => {
                if socket.write_all(&buf[..n]).await.is_err() {
                    return;
                }
            }
            Err(_) => {
                return;
            }
        }
    }
}
